The Data

The data used in this notebook is from the COVID-19 Data Repository by the Center for Systems Science and Engineering (CSSE) at Johns Hopkins University. The package used to retrieve data information can be found here.
Accessed dataset on: 2020-08-11

Preview of Dataset

data("coronavirus")
head(coronavirus)
coronavirus <- coronavirus %>%
  mutate(country = replace(country, country == "US", "United States"))

# Fill empty province with NA
coronavirus$province[coronavirus$province == ""] <- NA
# Population data
library(wpp2019)
data(pop)

keeps <- c("name","2020")
pop_2020 = pop[keeps]
names(pop_2020)[2] <- "population"
pop_2020 <- pop_2020 %>%
  mutate(name = replace(name, name == "United States of America", "United States")) %>%
  mutate(name = replace(name, name == "Iran (Islamic Republic of)", "Iran")) %>%
  mutate(name = replace(name, name == "Russian Federation", "Russia")) %>%
  mutate(name = replace(name, name == "Bolivia (Plurinational State of)", "Bolivia")) %>%
  mutate(name = replace(name, name == "Republic of Moldova", "Moldova")) %>%
  mutate(name = replace(name, name == "Venezuela (Bolivarian Republic of)", "Venezuela"))
pop_2020$population <- pop_2020$population*1000

# add population of each country
cases_pc_df <- left_join(coronavirus, pop_2020, by = c("country" = "name"))

Exploration of Cases Throughout The World

Countries With Highest Cases

Confirmed Case by Country

`summarise()` regrouping output by 'country', 'long', 'lat', 'population' (override with `.groups` argument)
top_10_confirmed_df <- world_confirmed_cases_df[1:10,]

world_confirmed_graph <-
 ggplot(data = top_10_confirmed_df,
        aes(x = reorder(country, total_cases),
            y = total_cases)) +
  labs( x = "Country",
        y = "Total Confirmed Cases",
        title = "Top 10 Countries With Higest Total Confirm Cases") +
  theme(plot.title = element_text(hjust = 0.5),
        axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
  geom_col(aes(fill = total_cases)) +
  scale_fill_gradient2(low = "thistle1", 
                       high = "mediumorchid1",
                       midpoint = median(top_10_confirmed_df$total_cases)) +
  geom_col(
    aes( y= 40),
    fill = "white",
    width = 1,
    alpha = 0.2,
    size = 0
  ) +
  geom_col(
    aes( y = 20),
    fill = "white",
    width = 1,
    alpha = 0.2,
    size = 0
  )

world_confirmed_graph

Death Cases by Country

world_death_cases_df <- coronavirus %>% 
  filter(type == "death") %>%
  group_by(country, long, lat, province) %>%
  summarise(total_deaths = sum(cases)) %>%
  arrange(-total_deaths)
`summarise()` regrouping output by 'country', 'long', 'lat' (override with `.groups` argument)
top_10_death_df <- world_death_cases_df[1:10,]

world_death_graph <-
 ggplot(data = top_10_death_df, aes(x = reorder(country, total_deaths), y = total_deaths)) +
  geom_col(aes(fill = total_deaths)) +
    labs( x = "Country",
        y = "Total Death Cases",
        title = "Top 10 Countries With Higest Death Cases") +
  theme(plot.title = element_text(hjust = 0.5),
        axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
  scale_fill_gradient2(low = "red", 
                       high = "red4",
                       midpoint = median(top_10_death_df$total_deaths)) +
  geom_col(
    aes( y= 40),
    fill = "white",
    width = 1,
    alpha = 0.2,
    size = 0
  ) +
  geom_col(
    aes( y = 20),
    fill = "white",
    width = 1,
    alpha = 0.2,
    size = 0
  )

world_death_graph

Recover Cases by Country

world_recovered_cases_df <- coronavirus %>% 
  filter(type == "recovered") %>%
  group_by(country, long, lat, province) %>%
  summarise(total_recovered = sum(cases)) %>%
  arrange(-total_recovered)
`summarise()` regrouping output by 'country', 'long', 'lat' (override with `.groups` argument)
top_10_recovered_df <- world_recovered_cases_df[1:10,]

world_recover_graph <-
 ggplot(data = top_10_recovered_df,
        aes(x = reorder(country, total_recovered),
            y = total_recovered)) +
  geom_col(aes(fill = total_recovered)) +
    labs( x = "Country",
        y = "Total Recovered Cases",
        title = "Top 10 Countries With Higest Total Recovered Cases") +
  theme(plot.title = element_text(hjust = 0.5),
        axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
  scale_fill_gradient2(low = "green", 
                       high = "green4",
                       midpoint = median(top_10_recovered_df$total_recovered)) +
  geom_col(
    aes( y= 40),
    fill = "white",
    width = 1,
    alpha = 0.2,
    size = 0
  ) +
  geom_col(
    aes( y = 20),
    fill = "white",
    width = 1,
    alpha = 0.2,
    size = 0
  )

world_recover_graph

Timeline

World Confirmed Cases Timeline

world_cases_by_date_df <- coronavirus %>% 
  filter(type == "confirmed") %>%
  group_by(date) %>%
  summarise(total_cases = sum(cases)) %>%
  arrange(-total_cases)
`summarise()` ungrouping output (override with `.groups` argument)
ggplot(world_cases_by_date_df, aes(date, total_cases)) +
  geom_line() +
  labs(x = "Month",
       y = "Cases",
       title ="Cumulative Confirmed Cases Worldwide") +
  theme(plot.title =element_text(hjust = 0.5)) +
  scale_x_date(labels = date_format("%b"), date_breaks = "1 month")

Timeline of Higest Confirmed Cases by Country

# List of countries to include in the graph
country_list <- c("United States", "Brazil", "India", "Russia", "Mexico", "China", "Canada")

top_country_df <- cases_pc_df %>% 
  filter(country %in% country_list) %>%
  filter(type == "confirmed") %>%
  group_by(date, country, population) %>%
  summarise(total_cases = sum(cases)) %>%
  arrange(-total_cases)
`summarise()` regrouping output by 'date', 'country' (override with `.groups` argument)
total_cases <- top_country_df$total_cases
population <- top_country_df$population
top_country_df$`Total Cases` <- total_cases*1000000/population

# draw a line plot of total_cases vs. date, grouped and colored by country
g <- ggplot(data = top_country_df,
            aes(x = date,
                y = `Total Cases`,
                color = country,
                group = country)) +
  geom_line() +
  labs(x= "Month",
       y=" Daily Confirmed Cases per Million People",
       title = "Daily Confirmed Cases by Country (2020)") +
  theme(plot.title = element_text(hjust = 0.5)) +
  scale_x_date(labels = date_format("%b"), date_breaks  ="1 month")

ggly <- ggplotly(p = g,
                 width = 1000,
                 height = 700,
                 tooltip = c("date", "Total Cases", "group"))
`group_by_()` is deprecated as of dplyr 0.7.0.
Please use `group_by()` instead.
See vignette('programming') for more help
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.
ggly

Worldmap Visualization

# Load packages and world map data
library(sf)
library(tmap)
library(spData)
library(viridis)
library(rnaturalearth)

world <-map_data("world")
breaks<- c(1, 30, 100, 1000, 50000, 100000)
labels<- c("1-29", "20-99", "100-999","1,000-49,999", "50,000-499,999", "100,000+")

confirm_map <- ggplot() +
  geom_polygon(data = world,
               aes(x = long, y = lat, group = group),
               fill = "grey", alpha = 0.3) +
  geom_point(data = world_confirmed_cases_df,
             aes(x = long,
                 y = lat,
                 size = total_cases,
                 color = total_cases,
                 text_country = country,
                 text_province = province,
                 text = paste("Deaths: ", total_cases)),
             alpha = 0.5) +
  scale_size_continuous(name = "Confirmed cases", trans="log", range=c(1,8),
                        breaks = breaks,labels=labels) +
  scale_colour_viridis_c(option = "plasma",
                         direction = -1,
                         name = "Confirmed cases",
                         trans = "log",
                         breaks = breaks,
                         labels = labels) +
  guides(colour=guide_legend()) + 
  theme_void() +
  labs(title = "Map of Confirmed Cases") +
  theme(legend.position="bottom",
        plot.title = element_text(hjust = 0.5))
Ignoring unknown aesthetics: text_country, text_province, text
confirm_map_plotly <- ggplotly(p = confirm_map,
                 width = 1000,
                 height = 700,
                 tooltip = c("text_country", "text_province", "text"))
Transformation introduced infinite values in discrete y-axisTransformation introduced infinite values in discrete y-axisNaNs produced
confirm_map_plotly
breaks<- c(1, 30, 100, 1000, 50000, 100000)
labels<- c("1-29", "20-99", "100-999","1,000-49,999", "50,000-499,999", "100,000+")

death_map <- ggplot() +
  geom_polygon(data = world,
               aes(x = long, y = lat, group = group),
               fill = "grey", alpha = 0.3) +
  geom_point(data = world_death_cases_df,
             aes(x = long,
                 y = lat,
                 size = total_deaths,
                 color = total_deaths,
                 text_country = country,
                 text_province = province,
                 text = paste("Deaths: ", total_deaths)),
             alpha = 0.5) +
  scale_size_continuous(name = "Death cases", trans="log", range=c(1,8),
                        breaks = breaks,labels=labels) +
  scale_colour_viridis_c(option = "inferno",
                         direction = -1,
                         name = "Death cases",
                         trans = "log",
                         breaks = breaks,
                         labels = labels) +
  guides(colour=guide_legend()) + 
  theme_void() +
  labs(title = "Map of Death Cases") +
  theme(legend.position="bottom",
        plot.title = element_text(hjust = 0.5))
Ignoring unknown aesthetics: text_country, text_province, text
death_map_plotly <- ggplotly(p = death_map,
                 width = 1000,
                 height = 700,
                 tooltip = c("text_country", "text_province", "text"))
Transformation introduced infinite values in discrete y-axisTransformation introduced infinite values in discrete y-axisNaNs produced
death_map_plotly

NA
LS0tCnRpdGxlOiAiQ09WSUQtMTkgVmlzdWFsaXphdGlvbnMiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKLS0tCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206MTAwcHg7Ij48L2Rpdj4KCiMgVGhlIERhdGEKVGhlIGRhdGEgdXNlZCBpbiB0aGlzIG5vdGVib29rIGlzIGZyb20gdGhlIFtDT1ZJRC0xOSBEYXRhIFJlcG9zaXRvcnkgYnkgdGhlIENlbnRlciBmb3IgU3lzdGVtcyBTY2llbmNlIGFuZCBFbmdpbmVlcmluZyAoQ1NTRSkgYXQgSm9obnMgSG9wa2lucyBVbml2ZXJzaXR5XShodHRwczovL2dpdGh1Yi5jb20vQ1NTRUdJU2FuZERhdGEvQ09WSUQtMTkpLiBUaGUgcGFja2FnZSB1c2VkIHRvIHJldHJpZXZlIGRhdGEgaW5mb3JtYXRpb24gY2FuIGJlIGZvdW5kIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vUmFtaUtyaXNwaW4vY29yb25hdmlydXMpLiA8YnI+PC9icj4KKipBY2Nlc3NlZCBkYXRhc2V0IG9uOiAqKiAyMDIwLTA4LTExCgpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KGNvcm9uYXZpcnVzKQojdXBkYXRlX2RhdGFzZXQoKQpgYGAKCjxkaXYgc3R5bGU9Im1hcmdpbi1ib3R0b206NTBweDsiPjwvZGl2PgojIyMjIFByZXZpZXcgb2YgRGF0YXNldApgYGB7cn0KZGF0YSgiY29yb25hdmlydXMiKQpoZWFkKGNvcm9uYXZpcnVzKQpgYGAKCmBgYHtyfQpjb3JvbmF2aXJ1cyA8LSBjb3JvbmF2aXJ1cyAlPiUKICBtdXRhdGUoY291bnRyeSA9IHJlcGxhY2UoY291bnRyeSwgY291bnRyeSA9PSAiVVMiLCAiVW5pdGVkIFN0YXRlcyIpKQoKIyBGaWxsIGVtcHR5IHByb3ZpbmNlIHdpdGggTkEKY29yb25hdmlydXMkcHJvdmluY2VbY29yb25hdmlydXMkcHJvdmluY2UgPT0gIiJdIDwtIE5BCmBgYAoKYGBge3J9CiMgUG9wdWxhdGlvbiBkYXRhCmxpYnJhcnkod3BwMjAxOSkKZGF0YShwb3ApCgprZWVwcyA8LSBjKCJuYW1lIiwiMjAyMCIpCnBvcF8yMDIwID0gcG9wW2tlZXBzXQpuYW1lcyhwb3BfMjAyMClbMl0gPC0gInBvcHVsYXRpb24iCnBvcF8yMDIwIDwtIHBvcF8yMDIwICU+JQogIG11dGF0ZShuYW1lID0gcmVwbGFjZShuYW1lLCBuYW1lID09ICJVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EiLCAiVW5pdGVkIFN0YXRlcyIpKSAlPiUKICBtdXRhdGUobmFtZSA9IHJlcGxhY2UobmFtZSwgbmFtZSA9PSAiSXJhbiAoSXNsYW1pYyBSZXB1YmxpYyBvZikiLCAiSXJhbiIpKSAlPiUKICBtdXRhdGUobmFtZSA9IHJlcGxhY2UobmFtZSwgbmFtZSA9PSAiUnVzc2lhbiBGZWRlcmF0aW9uIiwgIlJ1c3NpYSIpKSAlPiUKICBtdXRhdGUobmFtZSA9IHJlcGxhY2UobmFtZSwgbmFtZSA9PSAiQm9saXZpYSAoUGx1cmluYXRpb25hbCBTdGF0ZSBvZikiLCAiQm9saXZpYSIpKSAlPiUKICBtdXRhdGUobmFtZSA9IHJlcGxhY2UobmFtZSwgbmFtZSA9PSAiUmVwdWJsaWMgb2YgTW9sZG92YSIsICJNb2xkb3ZhIikpICU+JQogIG11dGF0ZShuYW1lID0gcmVwbGFjZShuYW1lLCBuYW1lID09ICJWZW5lenVlbGEgKEJvbGl2YXJpYW4gUmVwdWJsaWMgb2YpIiwgIlZlbmV6dWVsYSIpKQpwb3BfMjAyMCRwb3B1bGF0aW9uIDwtIHBvcF8yMDIwJHBvcHVsYXRpb24qMTAwMAoKIyBhZGQgcG9wdWxhdGlvbiBvZiBlYWNoIGNvdW50cnkKY2FzZXNfcGNfZGYgPC0gbGVmdF9qb2luKGNvcm9uYXZpcnVzLCBwb3BfMjAyMCwgYnkgPSBjKCJjb3VudHJ5IiA9ICJuYW1lIikpCgpgYGAKCiMgRXhwbG9yYXRpb24gb2YgQ2FzZXMgVGhyb3VnaG91dCBUaGUgV29ybGQKCiMjIENvdW50cmllcyBXaXRoIEhpZ2hlc3QgQ2FzZXMKCiMjIyBDb25maXJtZWQgQ2FzZSBieSBDb3VudHJ5CgpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp3b3JsZF9jb25maXJtZWRfY2FzZXNfZGYgPC0gY2FzZXNfcGNfZGYgJT4lIAogIGZpbHRlcih0eXBlID09ICJjb25maXJtZWQiKSAlPiUKICBncm91cF9ieShjb3VudHJ5LCBsb25nLCBsYXQsIHBvcHVsYXRpb24sIHByb3ZpbmNlKSAlPiUKICBzdW1tYXJpc2UodG90YWxfY2FzZXMgPSBzdW0oY2FzZXMpKSAlPiUKICBhcnJhbmdlKC10b3RhbF9jYXNlcykKYGBgCgpgYGB7cn0KdG9wXzEwX2NvbmZpcm1lZF9kZiA8LSB3b3JsZF9jb25maXJtZWRfY2FzZXNfZGZbMToxMCxdCgp3b3JsZF9jb25maXJtZWRfZ3JhcGggPC0KIGdncGxvdChkYXRhID0gdG9wXzEwX2NvbmZpcm1lZF9kZiwKICAgICAgICBhZXMoeCA9IHJlb3JkZXIoY291bnRyeSwgdG90YWxfY2FzZXMpLAogICAgICAgICAgICB5ID0gdG90YWxfY2FzZXMpKSArCiAgbGFicyggeCA9ICJDb3VudHJ5IiwKICAgICAgICB5ID0gIlRvdGFsIENvbmZpcm1lZCBDYXNlcyIsCiAgICAgICAgdGl0bGUgPSAiVG9wIDEwIENvdW50cmllcyBXaXRoIEhpZ2VzdCBUb3RhbCBDb25maXJtIENhc2VzIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKwogIGdlb21fY29sKGFlcyhmaWxsID0gdG90YWxfY2FzZXMpKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93ID0gInRoaXN0bGUxIiwgCiAgICAgICAgICAgICAgICAgICAgICAgaGlnaCA9ICJtZWRpdW1vcmNoaWQxIiwKICAgICAgICAgICAgICAgICAgICAgICBtaWRwb2ludCA9IG1lZGlhbih0b3BfMTBfY29uZmlybWVkX2RmJHRvdGFsX2Nhc2VzKSkgKwogIGdlb21fY29sKAogICAgYWVzKCB5PSA0MCksCiAgICBmaWxsID0gIndoaXRlIiwKICAgIHdpZHRoID0gMSwKICAgIGFscGhhID0gMC4yLAogICAgc2l6ZSA9IDAKICApICsKICBnZW9tX2NvbCgKICAgIGFlcyggeSA9IDIwKSwKICAgIGZpbGwgPSAid2hpdGUiLAogICAgd2lkdGggPSAxLAogICAgYWxwaGEgPSAwLjIsCiAgICBzaXplID0gMAogICkKCndvcmxkX2NvbmZpcm1lZF9ncmFwaApgYGAKCiMjIyBEZWF0aCBDYXNlcyBieSBDb3VudHJ5CgpgYGB7cn0Kd29ybGRfZGVhdGhfY2FzZXNfZGYgPC0gY29yb25hdmlydXMgJT4lIAogIGZpbHRlcih0eXBlID09ICJkZWF0aCIpICU+JQogIGdyb3VwX2J5KGNvdW50cnksIGxvbmcsIGxhdCwgcHJvdmluY2UpICU+JQogIHN1bW1hcmlzZSh0b3RhbF9kZWF0aHMgPSBzdW0oY2FzZXMpKSAlPiUKICBhcnJhbmdlKC10b3RhbF9kZWF0aHMpCgp0b3BfMTBfZGVhdGhfZGYgPC0gd29ybGRfZGVhdGhfY2FzZXNfZGZbMToxMCxdCgp3b3JsZF9kZWF0aF9ncmFwaCA8LQogZ2dwbG90KGRhdGEgPSB0b3BfMTBfZGVhdGhfZGYsIGFlcyh4ID0gcmVvcmRlcihjb3VudHJ5LCB0b3RhbF9kZWF0aHMpLCB5ID0gdG90YWxfZGVhdGhzKSkgKwogIGdlb21fY29sKGFlcyhmaWxsID0gdG90YWxfZGVhdGhzKSkgKwogICAgbGFicyggeCA9ICJDb3VudHJ5IiwKICAgICAgICB5ID0gIlRvdGFsIERlYXRoIENhc2VzIiwKICAgICAgICB0aXRsZSA9ICJUb3AgMTAgQ291bnRyaWVzIFdpdGggSGlnZXN0IERlYXRoIENhc2VzIikgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMSwgaGp1c3QgPSAxKSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdyA9ICJyZWQiLCAKICAgICAgICAgICAgICAgICAgICAgICBoaWdoID0gInJlZDQiLAogICAgICAgICAgICAgICAgICAgICAgIG1pZHBvaW50ID0gbWVkaWFuKHRvcF8xMF9kZWF0aF9kZiR0b3RhbF9kZWF0aHMpKSArCiAgZ2VvbV9jb2woCiAgICBhZXMoIHk9IDQwKSwKICAgIGZpbGwgPSAid2hpdGUiLAogICAgd2lkdGggPSAxLAogICAgYWxwaGEgPSAwLjIsCiAgICBzaXplID0gMAogICkgKwogIGdlb21fY29sKAogICAgYWVzKCB5ID0gMjApLAogICAgZmlsbCA9ICJ3aGl0ZSIsCiAgICB3aWR0aCA9IDEsCiAgICBhbHBoYSA9IDAuMiwKICAgIHNpemUgPSAwCiAgKQoKd29ybGRfZGVhdGhfZ3JhcGgKYGBgCgojIyMgUmVjb3ZlciBDYXNlcyBieSBDb3VudHJ5CgpgYGB7cn0Kd29ybGRfcmVjb3ZlcmVkX2Nhc2VzX2RmIDwtIGNvcm9uYXZpcnVzICU+JSAKICBmaWx0ZXIodHlwZSA9PSAicmVjb3ZlcmVkIikgJT4lCiAgZ3JvdXBfYnkoY291bnRyeSwgbG9uZywgbGF0LCBwcm92aW5jZSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX3JlY292ZXJlZCA9IHN1bShjYXNlcykpICU+JQogIGFycmFuZ2UoLXRvdGFsX3JlY292ZXJlZCkKCnRvcF8xMF9yZWNvdmVyZWRfZGYgPC0gd29ybGRfcmVjb3ZlcmVkX2Nhc2VzX2RmWzE6MTAsXQoKd29ybGRfcmVjb3Zlcl9ncmFwaCA8LQogZ2dwbG90KGRhdGEgPSB0b3BfMTBfcmVjb3ZlcmVkX2RmLAogICAgICAgIGFlcyh4ID0gcmVvcmRlcihjb3VudHJ5LCB0b3RhbF9yZWNvdmVyZWQpLAogICAgICAgICAgICB5ID0gdG90YWxfcmVjb3ZlcmVkKSkgKwogIGdlb21fY29sKGFlcyhmaWxsID0gdG90YWxfcmVjb3ZlcmVkKSkgKwogICAgbGFicyggeCA9ICJDb3VudHJ5IiwKICAgICAgICB5ID0gIlRvdGFsIFJlY292ZXJlZCBDYXNlcyIsCiAgICAgICAgdGl0bGUgPSAiVG9wIDEwIENvdW50cmllcyBXaXRoIEhpZ2VzdCBUb3RhbCBSZWNvdmVyZWQgQ2FzZXMiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93ID0gImdyZWVuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgaGlnaCA9ICJncmVlbjQiLAogICAgICAgICAgICAgICAgICAgICAgIG1pZHBvaW50ID0gbWVkaWFuKHRvcF8xMF9yZWNvdmVyZWRfZGYkdG90YWxfcmVjb3ZlcmVkKSkgKwogIGdlb21fY29sKAogICAgYWVzKCB5PSA0MCksCiAgICBmaWxsID0gIndoaXRlIiwKICAgIHdpZHRoID0gMSwKICAgIGFscGhhID0gMC4yLAogICAgc2l6ZSA9IDAKICApICsKICBnZW9tX2NvbCgKICAgIGFlcyggeSA9IDIwKSwKICAgIGZpbGwgPSAid2hpdGUiLAogICAgd2lkdGggPSAxLAogICAgYWxwaGEgPSAwLjIsCiAgICBzaXplID0gMAogICkKCndvcmxkX3JlY292ZXJfZ3JhcGgKYGBgCgojIyBUaW1lbGluZQoKIyMjIFdvcmxkIENvbmZpcm1lZCBDYXNlcyBUaW1lbGluZQpgYGB7cn0Kd29ybGRfY2FzZXNfYnlfZGF0ZV9kZiA8LSBjb3JvbmF2aXJ1cyAlPiUgCiAgZmlsdGVyKHR5cGUgPT0gImNvbmZpcm1lZCIpICU+JQogIGdyb3VwX2J5KGRhdGUpICU+JQogIHN1bW1hcmlzZSh0b3RhbF9jYXNlcyA9IHN1bShjYXNlcykpICU+JQogIGFycmFuZ2UoLXRvdGFsX2Nhc2VzKQoKZ2dwbG90KHdvcmxkX2Nhc2VzX2J5X2RhdGVfZGYsIGFlcyhkYXRlLCB0b3RhbF9jYXNlcykpICsKICBnZW9tX2xpbmUoKSArCiAgbGFicyh4ID0gIk1vbnRoIiwKICAgICAgIHkgPSAiQ2FzZXMiLAogICAgICAgdGl0bGUgPSJDdW11bGF0aXZlIENvbmZpcm1lZCBDYXNlcyBXb3JsZHdpZGUiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9ZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKwogIHNjYWxlX3hfZGF0ZShsYWJlbHMgPSBkYXRlX2Zvcm1hdCgiJWIiKSwgZGF0ZV9icmVha3MgPSAiMSBtb250aCIpCmBgYAoKIyMjIFRpbWVsaW5lIG9mIEhpZ2VzdCBDb25maXJtZWQgQ2FzZXMgYnkgQ291bnRyeQpgYGB7cn0KIyBMaXN0IG9mIGNvdW50cmllcyB0byBpbmNsdWRlIGluIHRoZSBncmFwaApjb3VudHJ5X2xpc3QgPC0gYygiVW5pdGVkIFN0YXRlcyIsICJCcmF6aWwiLCAiSW5kaWEiLCAiUnVzc2lhIiwgIk1leGljbyIsICJDaGluYSIsICJDYW5hZGEiKQoKdG9wX2NvdW50cnlfZGYgPC0gY2FzZXNfcGNfZGYgJT4lIAogIGZpbHRlcihjb3VudHJ5ICVpbiUgY291bnRyeV9saXN0KSAlPiUKICBmaWx0ZXIodHlwZSA9PSAiY29uZmlybWVkIikgJT4lCiAgZ3JvdXBfYnkoZGF0ZSwgY291bnRyeSwgcG9wdWxhdGlvbikgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX2Nhc2VzID0gc3VtKGNhc2VzKSkgJT4lCiAgYXJyYW5nZSgtdG90YWxfY2FzZXMpCgp0b3RhbF9jYXNlcyA8LSB0b3BfY291bnRyeV9kZiR0b3RhbF9jYXNlcwpwb3B1bGF0aW9uIDwtIHRvcF9jb3VudHJ5X2RmJHBvcHVsYXRpb24KdG9wX2NvdW50cnlfZGYkYFRvdGFsIENhc2VzYCA8LSB0b3RhbF9jYXNlcyoxMDAwMDAwL3BvcHVsYXRpb24KCiMgZHJhdyBhIGxpbmUgcGxvdCBvZiB0b3RhbF9jYXNlcyB2cy4gZGF0ZSwgZ3JvdXBlZCBhbmQgY29sb3JlZCBieSBjb3VudHJ5CmcgPC0gZ2dwbG90KGRhdGEgPSB0b3BfY291bnRyeV9kZiwKICAgICAgICAgICAgYWVzKHggPSBkYXRlLAogICAgICAgICAgICAgICAgeSA9IGBUb3RhbCBDYXNlc2AsCiAgICAgICAgICAgICAgICBjb2xvciA9IGNvdW50cnksCiAgICAgICAgICAgICAgICBncm91cCA9IGNvdW50cnkpKSArCiAgZ2VvbV9saW5lKCkgKwogIGxhYnMoeD0gIk1vbnRoIiwKICAgICAgIHk9IiBEYWlseSBDb25maXJtZWQgQ2FzZXMgcGVyIE1pbGxpb24gUGVvcGxlIiwKICAgICAgIHRpdGxlID0gIkRhaWx5IENvbmZpcm1lZCBDYXNlcyBieSBDb3VudHJ5ICgyMDIwKSIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkgKwogIHNjYWxlX3hfZGF0ZShsYWJlbHMgPSBkYXRlX2Zvcm1hdCgiJWIiKSwgZGF0ZV9icmVha3MgID0iMSBtb250aCIpCgpnZ2x5IDwtIGdncGxvdGx5KHAgPSBnLAogICAgICAgICAgICAgICAgIHdpZHRoID0gMTAwMCwKICAgICAgICAgICAgICAgICBoZWlnaHQgPSA3MDAsCiAgICAgICAgICAgICAgICAgdG9vbHRpcCA9IGMoImRhdGUiLCAiVG90YWwgQ2FzZXMiLCAiZ3JvdXAiKSkKCmdnbHkKYGBgCgoKCiMgV29ybGRtYXAgVmlzdWFsaXphdGlvbgpgYGB7cn0KIyBMb2FkIHBhY2thZ2VzIGFuZCB3b3JsZCBtYXAgZGF0YQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHRtYXApCmxpYnJhcnkoc3BEYXRhKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkocm5hdHVyYWxlYXJ0aCkKCndvcmxkIDwtbWFwX2RhdGEoIndvcmxkIikKYGBgCgpgYGB7cn0KYnJlYWtzPC0gYygxLCAzMCwgMTAwLCAxMDAwLCA1MDAwMCwgMTAwMDAwKQpsYWJlbHM8LSBjKCIxLTI5IiwgIjIwLTk5IiwgIjEwMC05OTkiLCIxLDAwMC00OSw5OTkiLCAiNTAsMDAwLTQ5OSw5OTkiLCAiMTAwLDAwMCsiKQoKY29uZmlybV9tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGQsCiAgICAgICAgICAgICAgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCksCiAgICAgICAgICAgICAgIGZpbGwgPSAiZ3JleSIsIGFscGhhID0gMC4zKSArCiAgZ2VvbV9wb2ludChkYXRhID0gd29ybGRfY29uZmlybWVkX2Nhc2VzX2RmLAogICAgICAgICAgICAgYWVzKHggPSBsb25nLAogICAgICAgICAgICAgICAgIHkgPSBsYXQsCiAgICAgICAgICAgICAgICAgc2l6ZSA9IHRvdGFsX2Nhc2VzLAogICAgICAgICAgICAgICAgIGNvbG9yID0gdG90YWxfY2FzZXMsCiAgICAgICAgICAgICAgICAgdGV4dF9jb3VudHJ5ID0gY291bnRyeSwKICAgICAgICAgICAgICAgICB0ZXh0X3Byb3ZpbmNlID0gcHJvdmluY2UsCiAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJEZWF0aHM6ICIsIHRvdGFsX2Nhc2VzKSksCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX3NpemVfY29udGludW91cyhuYW1lID0gIkNvbmZpcm1lZCBjYXNlcyIsIHRyYW5zPSJsb2ciLCByYW5nZT1jKDEsOCksCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGJyZWFrcyxsYWJlbHM9bGFiZWxzKSArCiAgc2NhbGVfY29sb3VyX3ZpcmlkaXNfYyhvcHRpb24gPSAicGxhc21hIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IC0xLAogICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJDb25maXJtZWQgY2FzZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnMgPSAibG9nIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGJyZWFrcywKICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGxhYmVscykgKwogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKCkpICsgCiAgdGhlbWVfdm9pZCgpICsKICBsYWJzKHRpdGxlID0gIk1hcCBvZiBDb25maXJtZWQgQ2FzZXMiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKY29uZmlybV9tYXBfcGxvdGx5IDwtIGdncGxvdGx5KHAgPSBjb25maXJtX21hcCwKICAgICAgICAgICAgICAgICB3aWR0aCA9IDEwMDAsCiAgICAgICAgICAgICAgICAgaGVpZ2h0ID0gNzAwLAogICAgICAgICAgICAgICAgIHRvb2x0aXAgPSBjKCJ0ZXh0X2NvdW50cnkiLCAidGV4dF9wcm92aW5jZSIsICJ0ZXh0IikpCgpjb25maXJtX21hcF9wbG90bHkKYGBgCgoKYGBge3J9CmJyZWFrczwtIGMoMSwgMzAsIDEwMCwgMTAwMCwgNTAwMDAsIDEwMDAwMCkKbGFiZWxzPC0gYygiMS0yOSIsICIyMC05OSIsICIxMDAtOTk5IiwiMSwwMDAtNDksOTk5IiwgIjUwLDAwMC00OTksOTk5IiwgIjEwMCwwMDArIikKCmRlYXRoX21hcCA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZCwKICAgICAgICAgICAgICAgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwKICAgICAgICAgICAgICAgZmlsbCA9ICJncmV5IiwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3BvaW50KGRhdGEgPSB3b3JsZF9kZWF0aF9jYXNlc19kZiwKICAgICAgICAgICAgIGFlcyh4ID0gbG9uZywKICAgICAgICAgICAgICAgICB5ID0gbGF0LAogICAgICAgICAgICAgICAgIHNpemUgPSB0b3RhbF9kZWF0aHMsCiAgICAgICAgICAgICAgICAgY29sb3IgPSB0b3RhbF9kZWF0aHMsCiAgICAgICAgICAgICAgICAgdGV4dF9jb3VudHJ5ID0gY291bnRyeSwKICAgICAgICAgICAgICAgICB0ZXh0X3Byb3ZpbmNlID0gcHJvdmluY2UsCiAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJEZWF0aHM6ICIsIHRvdGFsX2RlYXRocykpLAogICAgICAgICAgICAgYWxwaGEgPSAwLjUpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMobmFtZSA9ICJEZWF0aCBjYXNlcyIsIHRyYW5zPSJsb2ciLCByYW5nZT1jKDEsOCksCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGJyZWFrcyxsYWJlbHM9bGFiZWxzKSArCiAgc2NhbGVfY29sb3VyX3ZpcmlkaXNfYyhvcHRpb24gPSAiaW5mZXJubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAtMSwKICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiRGVhdGggY2FzZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnMgPSAibG9nIiwKICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGJyZWFrcywKICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGxhYmVscykgKwogIGd1aWRlcyhjb2xvdXI9Z3VpZGVfbGVnZW5kKCkpICsgCiAgdGhlbWVfdm9pZCgpICsKICBsYWJzKHRpdGxlID0gIk1hcCBvZiBEZWF0aCBDYXNlcyIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCgpkZWF0aF9tYXBfcGxvdGx5IDwtIGdncGxvdGx5KHAgPSBkZWF0aF9tYXAsCiAgICAgICAgICAgICAgICAgd2lkdGggPSAxMDAwLAogICAgICAgICAgICAgICAgIGhlaWdodCA9IDcwMCwKICAgICAgICAgICAgICAgICB0b29sdGlwID0gYygidGV4dF9jb3VudHJ5IiwgInRleHRfcHJvdmluY2UiLCAidGV4dCIpKQoKZGVhdGhfbWFwX3Bsb3RseQoKYGBgCgpgYGB7ciBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpicmVha3M8LSBjKDAsIDMwLCAxMDAsIDEwMDAsIDUwMDAwLCAxMDAwMDApCmxhYmVsczwtIGMoIjAiLCAiMS0yOSIsICIyMC05OSIsICIxMDAtOTk5IiwiMSwwMDAtNDksOTk5IiwgIjUwLDAwMCsiKQoKcmVjb3Zlcl9tYXAgPC0gZ2dwbG90KCkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGQsCiAgICAgICAgICAgICAgIGFlcyh4ID0gbG9uZywgeSA9IGxhdCxncm91cCA9IGdyb3VwKSwKICAgICAgICAgICAgICAgZmlsbCA9ICJncmV5IiwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3BvaW50KGRhdGEgPSB3b3JsZF9yZWNvdmVyZWRfY2FzZXNfZGYsCiAgICAgICAgICAgICBhZXMoeCA9IGxvbmcsCiAgICAgICAgICAgICAgICAgeSA9IGxhdCwKICAgICAgICAgICAgICAgICBzaXplID0gdG90YWxfcmVjb3ZlcmVkLAogICAgICAgICAgICAgICAgIGNvbG9yPXRvdGFsX3JlY292ZXJlZCwKICAgICAgICAgICAgICAgICB0ZXh0X2NvdW50cnkgPSBjb3VudHJ5LAogICAgICAgICAgICAgICAgIHRleHRfcHJvdmluY2UgPSBwcm92aW5jZSwKICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUoIlJlY292ZXJlZDogIiwgdG90YWxfcmVjb3ZlcmVkKSksCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX3NpemVfY29udGludW91cyhuYW1lID0gIlJlY292ZXJlZCBjYXNlcyIsIHRyYW5zPSJsb2ciLCByYW5nZT1jKDEsOCksCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGJyZWFrcyxsYWJlbHM9bGFiZWxzKSArCiAgc2NhbGVfY29sb3VyX3ZpcmlkaXNfYyhvcHRpb24gPSAidmlyaWRpcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAtMSwKICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiUmVjb3ZlcmVkIGNhc2VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zID0gImxvZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBicmVha3MsCiAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBsYWJlbHMpICsKICBndWlkZXMoY29sb3VyPWd1aWRlX2xlZ2VuZCgpKSArIAogIHRoZW1lX3ZvaWQoKSArCiAgbGFicyh0aXRsZSA9ICJNYXAgb2YgUmVjb3ZlcmVkIENhc2VzIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKCnJlY292ZXJfbWFwX3Bsb3RseSA8LSBnZ3Bsb3RseShwID0gcmVjb3Zlcl9tYXAsCiAgICAgICAgICAgICAgICAgd2lkdGggPSAxMDAwLAogICAgICAgICAgICAgICAgIGhlaWdodCA9IDcwMCwKICAgICAgICAgICAgICAgICB0b29sdGlwID0gYygidGV4dF9jb3VudHJ5IiwgInRleHRfcHJvdmluY2UiLCAidGV4dCIpKQoKcmVjb3Zlcl9tYXBfcGxvdGx5CmBgYAoKCg==